package com.example.springevent.event.async;

import java.math.BigDecimal;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import com.example.springevent.event.bo.IvdAddedEventBO;
import com.example.springevent.event.bo.IvdRemovedEventBO;
import com.example.springevent.event.event.IvdAddedEvent;
import com.example.springevent.ivd.domain.InvoiceKey;

//@Component
public class IvdEventListenerInvoiceAsyncHandler {
	private static final Logger log = LoggerFactory.getLogger(IvdEventListenerInvoiceAsyncHandler.class);

	/**
	 * 	@EventListener(classes = {XxxEvent.class}, condition = "") 
	 * 	入参：XxxEvent
	 * 	返回值：void，若为非void会进一步触发事件
	 * @param event
	 */
	@Async
	@EventListener(classes = {}, condition = "")
	public void handleIvdAddedEvent(IvdAddedEvent event) {
		log.info("handleIvdAddedEvent:");
		IvdAddedEventBO ivd = event.getIvdAddedEventBO();
		addVerifyAmt(new InvoiceKey(ivd.getInvoiceCode(), ivd.getInvoiceNo()), ivd.getVerifyAmt());
	}

	@Async
	@TransactionalEventListener(
			classes = IvdAddedEvent.class, 
			phase = TransactionPhase.AFTER_COMMIT, 
			fallbackExecution = false)	// 默认false,若改为true则表示非事务环境也执行监听方法
	public void handleIvdAddedEventInTran(IvdAddedEvent event) {
		log.info("handleIvdAddedEventInTran:");
		IvdAddedEventBO ivd = event.getIvdAddedEventBO();
		addVerifyAmt(new InvoiceKey(ivd.getInvoiceCode(), ivd.getInvoiceNo()), ivd.getVerifyAmt());
	}

	/**
	 * 
	 * @see PayloadApplicationEvent
	 * @see @EventListener
	 * @see
	 * @param ivd
	 */
	@EventListener(classes = IvdRemovedEventBO.class)
	public void handleIvdRemovedEvent(IvdRemovedEventBO ivd) {
		addVerifyAmt(new InvoiceKey(ivd.getInvoiceCode(), ivd.getInvoiceNo()), ivd.getVerifyAmt().negate());
	}

	public void addVerifyAmt(InvoiceKey invoice, BigDecimal verifyAmt) {
		log.info("Thread = [{}]，发票[{}]增加核销金额[{}]", Thread.currentThread().getName() ,invoice, verifyAmt);
	}

}
